import threading
from datetime import datetime, timedelta
import time
from sqlalchemy import text

from app.db import local_teaching_management_sessionLocal
from app.db.crud.teacher_management_query import material_query
from app.db.model import WorkQueue


class WorkQueueManager:
    # 入队判断
    def can_enqueue(self, file_path: str, ai_check: int) -> bool:
        with local_teaching_management_sessionLocal() as session:
            try:
                # 检测队列中是否有相同file_path且早前提交过
                ten_min_ago = datetime.now() - timedelta(minutes=10)
                exist_in_queue = session.execute(
                    text("""select 1 from work_queue where file_path = :file_path and submit_time > :submit_time"""),
                    {"file_path": file_path, "submit_time": ten_min_ago}).first()
                if exist_in_queue:
                    return False

                result = material_query.get_material_by_file_path(file_path)
                # 检查教案是否重新被提交过
                if ai_check == 1:
                    if result.get('ai_check_time1') is not None and result.get('ai_check_time1') == result.get(
                            'submit_time'):
                        return False
                elif ai_check == 2:
                    if result.get('ai_check_time2') is not None and result.get('ai_check_time2') == result.get(
                            'submit_time'):
                        return False
                elif ai_check == 3:
                    if result.get('ai_check_time3') is not None and result.get('ai_check_time3') == result.get(
                            'submit_time'):
                        return False

                return True
            except Exception as e:
                return False

    def enqueue(self, file_path: str, ai_check: int) -> bool:
        try:
            with local_teaching_management_sessionLocal() as session:
                if not self.can_enqueue(file_path, ai_check):
                    return False
                # 入队
                session.execute(text("""insert into work_queue(file_path, which_ai) value (:file_path, :ai_check)"""),
                                {"file_path": file_path, "ai_check": ai_check})
                session.commit()
                return True

        except Exception as e:
            return False

    def try_become_master(self) -> bool:
        with local_teaching_management_sessionLocal() as session:
            try:
                result = session.execute(text("""update work_queue set file_path  = '1' where file_path = '0'"""))
                session.commit()
                if result.rowcount > 0:
                    self.is_master = True
                    self.start_heartbeat()

                return result.rowcount
            except Exception as e:
                return False

    def start_heartbeat(self):
        self.running = True
        self.heartbeat_thread = threading.Thread(
            target=self.heartbeat_worker,
            daemon=True
        )
        self.heartbeat_thread.start()

    def heartbeat_worker(self):
        # 心跳工作线程
        while self.running:
            with local_teaching_management_sessionLocal() as session:
                try:
                    session.execute(text("""update work_queue set submit_time = now() where file_path = '1'"""))
                    session.commit()
                    time.sleep(10)
                except Exception as e:
                    time.sleep(5)

    def release_lock(self):
        self.running = False
        with local_teaching_management_sessionLocal() as session:
            try:
                session.execute(text("""update work_queue set file_path = '0' where file_path = '1'"""))
                session.commit()
                self.is_master = False
            except Exception as e:
                session.rollback()

    def check_master_health(self):
        # 检查主进程健康状态
        with local_teaching_management_sessionLocal() as session:
            try:
                result = session.execute(text("""select * from work_queue where file_path = '1'""")).first()
                if not result:
                    # 锁可用
                    return False
                last_heartbeat = result['submit_time']
                if datetime.now() - last_heartbeat > timedelta(seconds=20):
                    # 心跳超时，表示主进程已死亡，锁可用
                    session.execute(text("""update work_queue set file_path = '0' where file_path = '1'"""))
                    return False
                # 主进程未超时
                return True
            except Exception as e:
                return True

    def get_next_task(self):
        # 获取下一个待处理任务
        with local_teaching_management_sessionLocal() as session:
            try:
                result = session.execute(text(
                    """select file_path, ai_check from work_queue where file_path not in ('0', '1') order by submit_time limit 1""")).first()
                return result if result else None
            except Exception as e:
                return None

    def remove_task(self, file_path):
        # 删除任务
        with local_teaching_management_sessionLocal() as session:
            try:
                session.execute(text("""delete from work_queue where file_path = :file_path"""), {'file_path': file_path})
                session.commit()
            except Exception as e:
                return False

# 全局队列管理器实例
queue_manager = WorkQueueManager()

